#include <QList>
#include <QGraphicsEllipseItem>
#include <QDebug>

#include <iostream>
#include <algorithm>
#include <sys/time.h>

#include "base/geometry.h"
#include "base/Point.h"
#include "ui/PointItem.h"
#include "ui/GraphicScene.h"

GraphicScene::GraphicScene() :  _show_hull(false), _with_opti(false)
{
}

void GraphicScene::removePoint(Point* point)
{
    point_list::iterator it = find(_pts.begin(), _pts.end(), point);
    if (it != _pts.end()) {
        _pts.erase(it);
    }
}

void GraphicScene::plotPoints(point_list points)
{
    foreach(QGraphicsItem* item, this->items()) {
        if (item->group() == _points_group) {
            delete item;
        }
    }
    _points_group = new QGraphicsItemGroup(NULL, this);
    _pts.clear();
    _pts = points;
    for (point_list::const_iterator it = points.begin(); it != points.end(); ++it) {
        PointItem* item = new PointItem(*it, this);
        this->addItem(item);
    }
}
void GraphicScene::setOptimization(bool with_opti){
    _with_opti = with_opti;
    if (_algo) {
        _algo->with_diamond_opti(_with_opti);
    }
}

void GraphicScene::plotHull()
{
    foreach(QGraphicsItem* item, this->items()) {
        if (item->group() == _edges_group || item->group() == _diamond_group) {
            delete item;
        }
    }
    if (!_show_hull) return;
    _edges_group = new QGraphicsItemGroup(NULL, this);
    _diamond_group = new QGraphicsItemGroup(NULL, this);

    struct timeval begin_time, end_time;
    gettimeofday(&begin_time, NULL);
    point_list hull = _algo->compute_hull(_pts); // Appel de l'algorithme
    gettimeofday(&end_time, NULL);
    double duree = (end_time.tv_sec + end_time.tv_usec*1E-6) - (begin_time.tv_sec + begin_time.tv_usec*1E-6);

    _hull = hull;

    QPen penLine(Qt::red);
    penLine.setWidth(2);
    for (point_list::iterator it = hull.begin(); it != hull.end(); ++it) {
        Point* ptBegin = *it;
        Point* ptTarget = *hull.next_point(it);
        QGraphicsLineItem* item = this->addLine(ptBegin->x(), ptBegin->y(), ptTarget->x(), ptTarget->y(), penLine);
        _edges_group->addToGroup(item);
    }


    if (_with_opti) { // Tracé du losange
        point_list diamond = _pts.get_diamond();
        QPen penLineDiamond(Qt::blue, 2, Qt::DotLine);
        for (point_list::iterator it = diamond.begin(); it != diamond.end(); ++it) {
            Point* ptBegin = *it;
            Point* ptTarget = *diamond.next_point(it);
            QGraphicsLineItem* item = this->addLine(ptBegin->x(), ptBegin->y(), ptTarget->x(), ptTarget->y(), penLineDiamond);
            _diamond_group->addToGroup(item);
        }

    }
    char duration[20];
    sprintf(duration, "%f", duree);
    QString lblTemps = QString("Temps : ") + duration +QString(" s");
    QGraphicsTextItem* textItem = this->addText(lblTemps);
    _edges_group->addToGroup(textItem);
    textItem->setX(-20);
    textItem->setY(-30);


    char nb_points_txt[20];
    sprintf(nb_points_txt, "%d", hull.size());
    QString lblPoints = QString("Points dans l'enveloppe : ") + nb_points_txt;
    textItem = this->addText(lblPoints);
    _edges_group->addToGroup(textItem);
    textItem->setX(300);
    textItem->setY(-30);
}
